package com.rcd.viatornisl.android.fragment;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.rcd.viatornisl.android.R;
import com.rcd.viatornisl.android.model.Establishment;
import com.rcd.viatornisl.android.model.EstablishmentManager;
import com.rcd.viatornisl.android.model.adapters.EstablishmentAdapter;
import com.rcd.viatornisl.android.model.adapters.InterestAdapter;

public class EstablishmentFragment extends Fragment implements OnItemClickListener {

	private ListView _ListView;
	private List<Establishment> _Establishments;
	private static final String ESTABLISHMENTS_STATE = "establishments";

	private class LoadEstablishment extends AsyncTask<String, Void, List<Establishment>> {

		private Context _Context;
		private ProgressDialog _ProgressDialog;
		
		public LoadEstablishment(Context context) {
			// Setup the attributes
			this._Context = context;
			this._ProgressDialog = null;
		}
		
		private void removeEstablishmentsState() {
			// Get the shared preferences object
			SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this._Context);
					
			// Check if there is a valid key
			if (sharedPreferences.contains(ESTABLISHMENTS_STATE)) {
				// Remove previous state
				sharedPreferences.edit().remove(ESTABLISHMENTS_STATE);
			}
		}
		
		private void saveEstablishmentsToState(List<Establishment> establishments) {
			// Get the shared preferences object
			SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this._Context);
								
			// Edit the preferences. Set the content as JSON
			sharedPreferences.edit().putString(ESTABLISHMENTS_STATE, new Gson().toJson(establishments)).commit();			
		}
		
		@Override
		protected void onPreExecute() {
			// Create a progress dialog
			this._ProgressDialog = ProgressDialog.show(this._Context, this._Context.getResources().getString(R.string.establishment_loading_title), this._Context.getResources().getString(R.string.establishment_loading_description), true);
		}
		
		@Override
		protected List<Establishment> doInBackground(String... parameters) {
			// Create a manager
			EstablishmentManager establishmentManager = new EstablishmentManager(parameters[0]);
			
			// Load the establishments
			return establishmentManager.getEstablishments(Integer.parseInt(parameters[1]));
		}
		
		@Override
		protected void onPostExecute(List<Establishment> establishments) {
			// Default operations
			super.onPostExecute(establishments);
			
			// Clear previous state
			this.removeEstablishmentsState();
			
			// Save establishments to the state
			this.saveEstablishmentsToState(establishments);
			
			// Fill the establishment list
			EstablishmentFragment.this._Establishments = establishments;
			
			// Adapt
			EstablishmentFragment.this.adapt(this._Context);
			
			// Check if the progress dialog is running
			if ((this._ProgressDialog != null) && (this._ProgressDialog.isShowing())) {
				// Close the progress dialog
				this._ProgressDialog.dismiss();
			}
		}	
			
	}
			
	@SuppressWarnings("unchecked")
	private List<Establishment> loadEstablishmentsFromState(Context context) {		
		// Get the correct generic list type
		Type listType = new TypeToken<ArrayList<Establishment>>() {}.getType();
		
		// Get the default shared preferences
		SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);

		// Check if there is a valid key
		if (sharedPreferences.contains(ESTABLISHMENTS_STATE)) {
			// Retrieve the establishments
			return ((List<Establishment>)new Gson().fromJson(sharedPreferences.getString(ESTABLISHMENTS_STATE, ""), listType));
		}
		
		// Provide the return
		return null;
	}
	
	private void refreshEstablishments(Context context) {					
		// Check if it must load the establishments based on the arguments
		if (this.getArguments() == null) {
			// Load establishments from saved state
			this._Establishments = this.loadEstablishmentsFromState(context);							
		} else {
			// Load establishments
			new EstablishmentFragment.LoadEstablishment(context).execute(super.getString(R.string.base_url), Integer.toString(this.getArguments().getInt(InterestAdapter.INTERESTS_ID)));
		}
	}
	
	private void adapt(Context context) {	
		// If there is establishments, fill the view with the adapter
		if (this._Establishments != null) {
			// Create and setup the adapter
			EstablishmentAdapter establishmentAdapter = new EstablishmentAdapter(context, R.layout.establishment_list_item, this._Establishments);
			this._ListView.setAdapter(establishmentAdapter);
			this._ListView.setOnItemClickListener(this);	
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {			
		// Inflate the layout for this fragment and get the view
		View establishmentFragmentView = inflater.inflate(R.layout.establishment_fragment, container, false);
		
		// Set the attributes
		this._ListView = ((ListView)establishmentFragmentView.findViewById(R.id.establishmentListView));
		
		// Load the establishments
		this.refreshEstablishments(this.getActivity());
		
		// Adapt
		this.adapt(this.getActivity());			
		
		// Provide the return
		return establishmentFragmentView;
	}
	
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		// Create a toast object
		Toast toast = Toast.makeText(this.getActivity().getApplicationContext(), "Item " + (position + 1) + ": " + this._Establishments.get(position), Toast.LENGTH_SHORT);
		toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
		toast.show();
	}
		
}
